'use client';

import { useState, useRef, useEffect, useCallback, type KeyboardEvent } from 'react';
import useAuth from '@/hooks/useAuth';
import useChat from '@/hooks/useChat';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUsers, faEllipsisVertical, faPaperPlane, faTrashCan, faMagnifyingGlassPlus, faMagnifyingGlassMinus, faRotateRight, faClock, faCoins } from '@fortawesome/free-solid-svg-icons';
import './chat-sidebar.scss';

const MIN_FONT_SIZE = 11;
const MAX_FONT_SIZE = 19;
const DEFAULT_FONT_SIZE = 13;

type ChatSidebarProps = {
	onDonate?: () => void;
};

export default function ChatSidebar({ onDonate }: ChatSidebarProps = {}) {
	const { isAuthenticated } = useAuth();
	const { messages, systemMessages, participantCount, participants, sendMessage, clearMessages, refreshChat, requestParticipants, chatConnected } = useChat();
	const [inputValue, setInputValue] = useState('');
	const [fontSize, setFontSize] = useState(DEFAULT_FONT_SIZE);
	const [showMenu, setShowMenu] = useState(false);
	const [showTime, setShowTime] = useState(false);
	const messagesRef = useRef<HTMLDivElement>(null);
	const isAutoScrollRef = useRef(true);
	const [showParticipants, setShowParticipants] = useState(false);
	const menuRef = useRef<HTMLDivElement>(null);

	// 메시지 + 시스템 메시지를 시간순 병합
	const mergedMessages = (() => {
		const items: Array<
			| { type: 'chat'; data: typeof messages[number] }
			| { type: 'system'; data: typeof systemMessages[number] }
		> = [];

		messages.forEach((m) => items.push({ type: 'chat', data: m }));
		systemMessages.forEach((m) => items.push({ type: 'system', data: m }));

		items.sort((a, b) => {
			const timeA = a.type === 'chat' ? a.data.sentAt : a.data.receivedAt;
			const timeB = b.type === 'chat' ? b.data.sentAt : b.data.receivedAt;
			return new Date(timeA).getTime() - new Date(timeB).getTime();
		});

		return items;
	})();

	// 자동 스크롤
	useEffect(() => {
		const el = messagesRef.current;
		if (!el || !isAutoScrollRef.current) return;
		el.scrollTop = el.scrollHeight;
	}, [mergedMessages.length]);

	// 스크롤 이벤트로 자동 스크롤 제어
	const handleScroll = useCallback(() => {
		const el = messagesRef.current;
		if (!el) return;
		const threshold = 50;
		isAutoScrollRef.current = el.scrollTop + el.clientHeight >= el.scrollHeight - threshold;
	}, []);

	// 메뉴 외부 클릭 닫기
	useEffect(() => {
		if (!showMenu) return;
		const handleClick = (e: MouseEvent) => {
			if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
				setShowMenu(false);
			}
		};
		document.addEventListener('mousedown', handleClick);
		return () => document.removeEventListener('mousedown', handleClick);
	}, [showMenu]);

	const handleSend = useCallback(() => {
		if (!inputValue.trim()) return;
		sendMessage(inputValue);
		setInputValue('');
	}, [inputValue, sendMessage]);

	const handleKeyDown = useCallback((e: KeyboardEvent<HTMLInputElement>) => {
		if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
			e.preventDefault();
			handleSend();
		}
	}, [handleSend]);

	const handleClear = useCallback(() => {
		clearMessages();
		setShowMenu(false);
	}, [clearMessages]);

	const handleFontIncrease = useCallback(() => {
		setFontSize((prev) => Math.min(prev + 2, MAX_FONT_SIZE));
		setShowMenu(false);
	}, []);

	const handleFontDecrease = useCallback(() => {
		setFontSize((prev) => Math.max(prev - 2, MIN_FONT_SIZE));
		setShowMenu(false);
	}, []);

	const handleRefresh = useCallback(() => {
		setShowMenu(false);
		refreshChat();
	}, [refreshChat]);

	const handleToggleTime = useCallback(() => {
		setShowTime((prev) => !prev);
		setShowMenu(false);
	}, []);

	const handleShowParticipants = useCallback(() => {
		requestParticipants();
		setShowParticipants(true);
	}, [requestParticipants]);

	const handleCloseParticipants = useCallback(() => {
		setShowParticipants(false);
	}, []);

	const formatTime = (dateStr: string) => {
		const date = new Date(dateStr);
		return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
	};

	return (
		<div className='chat-sidebar'>
			{/* 헤더 */}
			<div className='chat-header'>
				<span className='chat-header-title'>실시간 채팅</span>
				<div className='chat-header-actions'>
					<button type='button' className='chat-participant-count' title='참여자 보기' onClick={handleShowParticipants}>
						<FontAwesomeIcon icon={faUsers} />
						<span>{participantCount}명</span>
					</button>
					<div className='chat-menu-wrapper' ref={menuRef}>
						<button type='button' title='메뉴' onClick={() => setShowMenu((prev) => !prev)}>
							<FontAwesomeIcon icon={faEllipsisVertical} />
						</button>
						{showMenu && (
							<div className='chat-menu'>
								<button type='button' onClick={handleClear}>
									<FontAwesomeIcon icon={faTrashCan} />
									<span>채팅 지우기</span>
								</button>
								<button type='button' onClick={handleToggleTime}>
									<FontAwesomeIcon icon={faClock} />
									<span>시간 {showTime ? '숨기기' : '보기'}</span>
								</button>
								<button type='button' onClick={handleFontIncrease} disabled={fontSize >= MAX_FONT_SIZE}>
									<FontAwesomeIcon icon={faMagnifyingGlassPlus} />
									<span>글자 크게</span>
								</button>
								<button type='button' onClick={handleFontDecrease} disabled={fontSize <= MIN_FONT_SIZE}>
									<FontAwesomeIcon icon={faMagnifyingGlassMinus} />
									<span>글자 작게</span>
								</button>
								<button type='button' onClick={handleRefresh}>
									<FontAwesomeIcon icon={faRotateRight} />
									<span>새로고침</span>
								</button>
							</div>
						)}
					</div>
				</div>
			</div>

			{/* 메시지 영역 */}
			<div className='chat-messages' ref={messagesRef} onScroll={handleScroll} style={{ fontSize: `${fontSize}px` }}>
				{!chatConnected && (
					<div className='chat-system'>채팅 서버에 연결 중...</div>
				)}
				{mergedMessages.map((item, index) => {
					if (item.type === 'system') {
						return (
							<div key={`sys-${item.data.id}`} className='chat-system'>
								{item.data.content}
							</div>
						);
					}

					const msg = item.data;
					return (
						<div key={`msg-${index}`} className='chat-message'>
							{showTime && <span className='chat-message-time'>{formatTime(msg.sentAt)}</span>}
							<span className='chat-message-name'>{msg.memberName || msg.memberSID}</span>
							<span className='chat-message-content'>{msg.content}</span>
						</div>
					);
				})}
			</div>

			{/* 입력 영역 */}
			<div className='chat-input-area'>
				{isAuthenticated ? (
					<div className='chat-input-row'>
						<input
							type='text'
							placeholder='메시지를 입력하세요'
							value={inputValue}
							onChange={(e) => setInputValue(e.target.value)}
							onKeyDown={handleKeyDown}
							maxLength={500}
							disabled={!chatConnected}
						/>
						{onDonate && (
							<button type='button' title='후원하기' onClick={onDonate} className='chat-donate-btn'>
								<FontAwesomeIcon icon={faCoins} />
							</button>
						)}
						<button type='button' title='전송' onClick={handleSend} disabled={!chatConnected || !inputValue.trim()}>
							<FontAwesomeIcon icon={faPaperPlane} />
						</button>
					</div>
				) : (
					<div className='chat-login-notice'>
						<a href='/login'>로그인</a> 후 채팅에 참여하세요
					</div>
				)}
			</div>

			{/* 참여자 목록 패널 */}
			{showParticipants && (
				<>
					<div className='chat-participants-overlay' onClick={handleCloseParticipants} />
					<div className='chat-participants-dialog'>
						<div className='chat-participants-header'>
							<h3>참여자 ({participantCount}명)</h3>
							<button type='button' onClick={handleCloseParticipants} aria-label='닫기'>&times;</button>
						</div>
						<ul className='chat-participants-list'>
							{participants.length === 0 && participantCount === 0 ? (
								<li className='chat-participants-empty'>참여자가 없습니다</li>
							) : (
								<>
									{participants.map((p) => (
										<li key={p.memberName}>
											<FontAwesomeIcon icon={faUsers} className='chat-participant-icon' />
											<span>{p.memberName}</span>
										</li>
									))}
									{participantCount - participants.length > 0 && (
										<li className='chat-participants-guest'>
											<span>비회원 {participantCount - participants.length}명</span>
										</li>
									)}
								</>
							)}
						</ul>
					</div>
				</>
			)}
		</div>
	);
}